import time
import threading
from concurrent.futures import ThreadPoolExecutor
import tkinter as tk
from ..utils.types import Uds_Request_Type
from datetime import datetime
import sys

# 此处导入会导致循环导入
# from ..apps.uds_ui.uds_manual_main_window import GLOBAL_MASTER_UI
# from ..globals import GLOBAL_MASTER_UI


class WorkFlow:

    def __init__(self, stepCounts=5):
        # 启动工作流的界面，用于相互通讯
        self._step = 0
        self._stepCounts = stepCounts
        self.handle_dict = {}
        self.pool = ThreadPoolExecutor(max_workers=2)

        # 自动创建每个step的OverFlag信号
        for i in range(stepCounts):
            setattr(self, f"step{i}OverFlag", False)
        # 创建循环步数的每个工作函数
        self.setHandleDict()

    def setStepOverFlag(self, step):
        setattr(self, f"step{step}OverFlag", True)

    def resetStepOverFlag(self, step):
        setattr(self, f"step{step}OverFlag", False)

    def setHandleDict(self):
        for i in range(self.stepCounts):
            self.handle_dict[i] = getattr(
                self, "handleStep" + str(i), self.defaultHandle)

    def defaultHandle(self):
        time.sleep(1)
        print("defaultHandle")
        self.nextStep()
        pass

    @property
    def stepCounts(self):
        return self._stepCounts

    def nextStep(self):
        if self._step < self.stepCounts - 1:
            self._step += 1
        else:
            self.resetStep()

    def prevStep(self):
        if self._step > 0:
            self._step -= 1

    def resetStep(self):
        self._step = 0

    def getStep(self):
        return self._step

    def setStep(self, step):
        self._step = step

    def handleStep0(self, *args, **kwargs):
        time.sleep(1)
        print("step0")
        self.nextStep()

    def handleStep1(self, *args, **kwargs):
        time.sleep(1)
        print("step1")
        self.nextStep()

    def handleStep2(self, *args, **kwargs):
        time.sleep(1)
        print("step2")
        self.nextStep()

    def handleStep3(self, *args, **kwargs):
        time.sleep(1)
        print("step3")
        self.nextStep()

    def set_handle_steps(self, step, handle):
        self.handle_dict[step] = handle


class FuncJobBase:
    def __init__(self, funcCounts=5, masterUI=None) -> None:
        self.funcCounts = funcCounts
        self.masterUI = masterUI
        self.pool = ThreadPoolExecutor(max_workers=1)

    def display_sendUds(self, uds_request: Uds_Request_Type):
        print(f'[file:{__file__}]=>[line:{
              (sys._getframe().f_lineno)}]==>uds_request:{uds_request}')

    def display_recvUds_positive(self, response):
        print(f'[file:{__file__}]=>[line:{
              (sys._getframe().f_lineno)}]==>response:{response}')

    def display_recvUds_negative(self, response):
        print(f'[file:{__file__}]=>[line:{
              (sys._getframe().f_lineno)}]==>response:{response}')

    def positive_resp_handle(self, response):
        print(f'[file:{__file__}]=>[line:{
              (sys._getframe().f_lineno)}]==>response:{response}')


class FuncJobModel(FuncJobBase):

    def display_sendUds(self, uds_request: Uds_Request_Type):
        listView = self.masterUI.listSendUds
        src_addr = uds_request.req_src_addr
        dst_addr = uds_request.req_dst_addr
        sid = uds_request.req_sid
        param_len = uds_request.req_param_len
        data = uds_request.req_data_1
        timestamp = f'{datetime.now():%Y-%m-%d %H:%M:%S}'

        listView.insert(tk.END, f'time:{timestamp},src:{hex(src_addr)},dst:{
                        hex(dst_addr)},sid:{hex(sid)},param_len:{hex(param_len)},param:{" ".join([hex(item) for item in data])}')
        listView.see(tk.END)

    def display_recvUds_positive(self, positive_resp):

        listView = self.masterUI.listRecvUds
        listView.insert(
            tk.END, positive_resp)
        listView.see(tk.END)

    def display_recvUds_negative(self, negative_resp):
        listView = self.masterUI.listRecvUds
        listView.insert(tk.END, negative_resp)
        listView.itemconfig(
            tk.END, background='pink')

    def step_btn_active(self, step):
        self.TESTER.modelWin.stepStart_btn_DICT[step].config(background='green',
                                                             state=tk.NORMAL)

    def step_btn_deActive(self, step):
        self.TESTER.modelWin.stepStart_btn_DICT[step].config(background='gray',
                                                             state=tk.NORMAL)

    def handleWrap(self, func, step):
        def wrap():
            self.step_btn_active(step)
            func()
            self.step_btn_deActive(step)
            self.nextStep()
        wrap()


class FuncJobUnit(FuncJobBase):

    def display_sendUds(self, uds_request: Uds_Request_Type):
        listView = self.masterUI.listSendUds
        src_addr = uds_request.req_src_addr
        dst_addr = uds_request.req_dst_addr
        sid = uds_request.req_sid
        param_len = uds_request.req_param_len
        data = uds_request.req_data_1
        timestamp = f'{datetime.now():%Y-%m-%d %H:%M:%S}'
        listView.insert(tk.END, f'time:{timestamp},src:{hex(src_addr)},dst:{
                        hex(dst_addr)},sid:{hex(sid)},param_len:{hex(param_len)},param:{" ".join([hex(item) for item in data])}')

        listView.see(tk.END)

        # 如果有额外加工要放在handle_response 的 cb回调函数中
        # listView_insert(tk.END, ''.join(int(item, 16) for item in data))

    def display_recvUds_positive(self, positive_resp):

        listView = self.masterUI.listRecvUds
        listView.insert(
            tk.END, positive_resp)
        listView.see(tk.END)

    def display_recvUds_negative(self, negative_resp):
        listView = self.masterUI.listRecvUds
        listView.insert(tk.END, negative_resp)
        listView.itemconfig(
            tk.END, background='pink')

    def step_btn_active(self, func):
        self.TESTER.unitWin.funcStart_btn_DICT[func].config(background='green',
                                                            state=tk.NORMAL)

    def step_btn_deActive(self, func):
        self.TESTER.unitWin.funcStart_btn_DICT[func].config(background='gray',
                                                            state=tk.NORMAL)


def main():
    wf = WorkFlow(None)
    wf.run()
    pass


if __name__ == '__main__':
    main()
